package com.dctp.ems.controller;

import com.dctp.common.cache.FuturesCache;
import com.dctp.common.cache.TradeTimeCache;
import com.dctp.common.controller.BaseController;
import com.dctp.common.utils.CollectUtil;
import com.dctp.common.utils.DateUtil;
import com.dctp.common.vo.JsonResult;
import com.dctp.common.vo.PageResult;
import com.jfinal.aop.Before;
import com.jfinal.core.Path;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;

@Path("/liquidationRule")
public class LiquidationRuleController extends BaseController {

    /**
     * GET /liquidationRule/list
     * 分页查询强平规则
     */
    public void list() {
        int page = getInt("currentPage", 1);
        int pageSize = getInt("pageSize", 20);
        Long futuresId = getParaToLong("futures_id");
        StringBuilder where = new StringBuilder(" WHERE 1=1 ");
        List<Object> params = new ArrayList<>();
        if (futuresId != null) {
            where.append(" AND t.futures_id = ?");
            params.add(futuresId);
        }
        String select = "SELECT id,trade_time_id,update_time,force_close_time,futures_id,status ";
        String from = "FROM dctp_liquidation_rule  " +
            where + " ORDER BY id asc ";
        var p = Db.paginate(page, pageSize, select, from, params.toArray());
        if (CollectUtil.isNotEmpty(p.getList())) {
            p.getList().forEach(item -> {
                Record futures = FuturesCache.get(item.getLong("futures_id"));
                if (null != futures) {
                    item.set("futures_name", futures.getStr("name"));
                }
                Record tradeTime = TradeTimeCache.getTradeTime(item.getLong("trade_time_id"));
                if (null != tradeTime) {
                    tradeTime.remove("id");
                    item.setColumns(tradeTime.getColumns());
                }
            });
        }
        renderJson(JsonResult.successWithData(
            new PageResult<>(p.getList(), p.getTotalRow(), pageSize, page)
        ));
    }

    /**
     * POST /liquidationRule/add
     * 添加强平规则
     */
    @Before(Tx.class)
    public void add() {
        Record body = jsonBody();
        if (body.get("futures_id") == null) {
            renderJson(JsonResult.failWithMessage("futures_id不能为空"));
            return;
        }
        if (!isForceCloseTimeValid(body)) {
            renderJson(JsonResult.failWithMessage("force_close_time必须在trade_start_time和trade_end_time之间"));
            return;
        }
        // 检查唯一
        Long exist = Db.queryLong("SELECT id FROM dctp_liquidation_rule WHERE futures_id=? AND trade_start_time=? AND trade_end_time=?", body.getLong("futures_id"), body.getStr("trade_start_time"), body.getStr("trade_end_time"));
        if (exist != null) {
            renderJson(JsonResult.failWithMessage("该品种该时间段已存在"));
            return;
        }
        body.set("create_time", DateUtil.now());
        if (!Db.save("dctp_liquidation_rule", body)) {
            throw new RuntimeException("新增强平规则失败");
        }
        renderJson(JsonResult.success());
    }

    /**
     * POST /liquidationRule/update/:id
     * 更新强平规则
     */
    @Before(Tx.class)
    public void update() {
        Long id = getParaToLong(0);
        if (id == null) {
            renderJson(JsonResult.failWithMessage("参数缺失"));
            return;
        }
        Record body = jsonBody();
        if (body.getColumns().isEmpty()) {
            renderJson(JsonResult.failWithMessage("无有效字段"));
            return;
        }
        if (!isForceCloseTimeValid(body)) {
            renderJson(JsonResult.failWithMessage("强平时间必须在开始时间和结束时间之间"));
            return;
        }

        body.set("id", id)
            .set("update_time", DateUtil.now());
        body.remove("begin_time");
        body.remove("end_time");
        if (id == 0) {
            body.set("create_time", DateUtil.now());
            body.set("id", null); // 新增时不需要设置id
            if (!Db.save("dctp_liquidation_rule", body)) {
                renderJson(JsonResult.fail("设置失败"));
                return;
            }
        }else {
            boolean updated = Db.update("dctp_liquidation_rule", body);
            if (!updated) {
                renderJson(JsonResult.failWithMessage("更新失败或记录不存在"));
                return;
            }
        }
        renderJson(JsonResult.success());
    }

    /**
     * POST /liquidationRule/delete/:id
     * 删除强平规则
     */
    @Before(Tx.class)
    public void delete() {
        Long id = getParaToLong(0);
        if (id == null) {
            renderJson(JsonResult.failWithMessage("参数缺失"));
            return;
        }
        int r = Db.update("DELETE FROM dctp_liquidation_rule WHERE id=?", id);
        if (r == 0) {
            renderJson(JsonResult.failWithMessage("删除失败或记录不存在"));
        } else {
            renderJson(JsonResult.success());
        }
    }

    /**
     * GET /liquidationRule/all
     * 获取所有启用的强平规则
     */
    public void all() {
        List<Record> list = Db.find("SELECT * FROM dctp_liquidation_rule WHERE segment_enabled=1 AND rule_effective=1 ORDER BY futures_id ASC, segment_no ASC");
        renderJson(JsonResult.successWithData(list));
    }

    private boolean isForceCloseTimeValid(Record body) {
        String start = body.getStr("begin_time");
        String end = body.getStr("end_time");
        String force = body.getStr("force_close_time");
        if (start == null || end == null || force == null) return false;
        try {
            LocalTime tStart = LocalTime.parse(start);
            LocalTime tEnd = LocalTime.parse(end);
            LocalTime tForce = LocalTime.parse(force);
            // force_close_time 必须在 start 和 end 之间（含等于）
            return !tForce.isBefore(tStart) && !tForce.isAfter(tEnd);
        } catch (Exception e) {
            return false;
        }
    }
}
